package com.bsoft.gol.hbs.service.impl;

import com.bsoft.gol.hbs.bean.Vo.ModuleConfigVo;
import com.bsoft.gol.hbs.bean.request.BasePropertyConfigRequest;
import com.bsoft.gol.hbs.bean.request.QueryPropertyConfigRequest;
import com.bsoft.gol.hbs.dao.BasePropertyConfigDAO;
import com.bsoft.gol.hbs.service.BasePropertyConfigService;
import com.bsoft.gol.hbs.utils.CommonUtils;
import com.google.common.collect.ImmutableMap;
import ctd.account.UserRoleToken;
import ctd.controller.exception.ControllerException;
import ctd.dictionary.Dictionary;
import ctd.dictionary.DictionaryItem;
import ctd.dictionary.controller.DictionaryController;
import ctd.net.rpc.json.JSONResponseBean;
import ctd.net.rpc.util.ServiceAdapter;
import ctd.parameter.Parameter;
import ctd.parameter.controller.ParameterController;
import ctd.spring.boot.annotation.RpcAccess;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.annotation.RpcService;
import ctd.util.context.ContextUtils;
import hcn.base.*;
import hcn.bean.OrgBean;
import hcn.util.RpcUserToken;
import hcn.util.validation.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.atag.core.model.bbp.ParameterVO;
import org.atag.core.model.common.ObjectIdDTO;
import org.atag.core.model.common.PropertyCodeDTO;
import org.atag.util.bbp.ParamUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import service.rpc.BasePropertyConfigIntf;
import service.rpc.OrgCloudIntf;
import service.rpc.OrganizationInfoIntf;
import service.rpc.ServiceOpenIntf;

import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统参数对外提供rpc服务类
 *
 * @author yaosj
 */
@SsdevService("basePropertyConfig")
public class BasePropertyConfigServiceImpl implements BasePropertyConfigService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BasePropertyConfigServiceImpl.class);

    @Autowired
    private BasePropertyConfigDAO basePropertyConfigDAO;

    @Autowired
    private OrganizationInfoIntf organizationInfoIntf;

    @Autowired
    private ServiceOpenIntf serviceOpenIntf;

    @Autowired
    private OrgCloudIntf orgCloudIntf;

    @Autowired
    private BasePropertyConfigIntf basePropertyConfigIntf;

    @Value("${gol.app.code:}")
    private String golAppCode;

    /**
     * 获取功能配置菜单
     *
     * @return
     */
    @Override
    public List<ModuleConfigVo> queryModuleMenuList() throws ControllerException {
        List<ModuleConfigVo> list = new ArrayList<ModuleConfigVo>();
        ModuleConfigVo moduleConfigVo = new ModuleConfigVo();
        moduleConfigVo.setTenantId(RpcUserToken.getTenantId());
        moduleConfigVo.setTenantName("健康城市");
        List<OrgBean> orgBeanList = organizationInfoIntf.queryOrgInfoByTenantId(RpcUserToken.getTenantId());
        moduleConfigVo.setOrgBeanList(orgBeanList);
        list.add(moduleConfigVo);
        return list;
    }

    /**
     * 获取参数配置列表
     *
     * @param objectId 来源id(租户id或机构id)
     * @return
     */
    @Override
    @RpcAccess(auth = false)
    public List<BasePropertyConfig> queryAllPropertyConfig(String objectId, String moduleId, String propertyCode) throws ControllerException {
        if (StringUtils.isEmpty(moduleId) && StringUtils.isEmpty(propertyCode)) {
            throw new ControllerException("参数异常");
        }
        if (StringUtils.isEmpty(objectId)) {
            objectId = RpcUserToken.getTenantId();
        }
        String code = StringUtils.isEmpty(propertyCode) ? moduleId : propertyCode;
        PropertyCodeDTO propertyCodeDTO = PropertyCodeDTO.builder().propertyCode(code).functionId(golAppCode).build();
        ObjectIdDTO objectIdDTO = ObjectIdDTO.builder().objectId(objectId).build();
        List<ParameterVO> params = ParamUtils.getParamsByModuleId(propertyCodeDTO, objectIdDTO);
        if (CollectionUtils.isEmpty(params)) {
            return Collections.emptyList();
        }
        return params.stream().map(p -> {
            BasePropertyConfig config = new BasePropertyConfig();
            config.setPropertyName(p.getName());
            config.setPropertyCode(p.getCode());
            config.setPropertyData(p.getValue());
            config.setUnit(p.getDes());
            return config;
        }).collect(Collectors.toList());
    }

    @Override
    @RpcService
    public List<BasePropertyConfig> querySystemPropertyConfigList(BasePropertyConfigRequest request) throws ControllerException {
        List<BasePropertyConfig> basePropertyConfigList = new ArrayList<>();
        for (int i = 0; i < request.getModuleList().size(); i++) {
            basePropertyConfigList.addAll(queryAllPropertyConfig(request.getObjectId(), request.getModuleList().get(i), request.getPropertyCodeList().get(i)));
        }
        return basePropertyConfigList;
    }

    /**
     * 获取参数配置列表( 参数名称 、描述  模糊查询)
     *
     * @return
     */
    @Override
    public List<BasePropertyConfig> queryAllPropertyConfigByFuzzy(QueryPropertyConfigRequest request) throws ControllerException {
        if (StringUtils.isEmpty(request.getObjectId())) {
            throw new ControllerException(0, "参数不能为空:objectId");
        }
        List<BasePropertyConfig> list = basePropertyConfigDAO.queryPropertyConfigByFuzzy(request);
        if (CommonUtils.isNotEmpty(list) && StringUtils.isEmpty(list.get(0).getObjectName())) {
            Organization organization = organizationInfoIntf.getOrgDetailByOrgId(request.getObjectId());
            for (BasePropertyConfig basePropertyConfig : list) {
                basePropertyConfig.setObjectName(organization.getFullName());
            }
        }
        return list;
    }


    /**
     * 保存参数配置
     *
     * @param basePropertyConfig
     * @throws ControllerException
     */
    @Override
    public void saveBasePropertyConfig(BasePropertyConfig basePropertyConfig) throws Exception {
        if (StringUtils.isEmpty(String.valueOf(basePropertyConfig.getPropertyId())) || StringUtils.isEmpty(basePropertyConfig.getObjectId())) {
            throw new ControllerException(0, "参数不能为空:propertyId,objectId");
        }
        String objectName = "";
        switch (basePropertyConfig.getPropertyLevel()) {
            case "1":
                objectName = "健康城市管理平台";
                break;
            case "2":
                objectName = "健康城市";
                break;
            case "3":
                Organization organization = organizationInfoIntf.getOrgDetailByOrgId(basePropertyConfig.getObjectId());
                objectName = organization != null ? organization.getFullName() : "";
                break;
        }
        BasePropertyConfig basePropertyConfig_exist = basePropertyConfigDAO.getPropertyConfigByPropertyCode(basePropertyConfig.getPropertyCode(), basePropertyConfig.getObjectId());
        if (basePropertyConfig_exist != null) {
            if (StringUtils.isNotEmpty(basePropertyConfig.getPropertyData())) {
                basePropertyConfig_exist.setPropertyData(basePropertyConfig.getPropertyData());
            }
            basePropertyConfig_exist.setObjectName(objectName);
            basePropertyConfig_exist.setObjectId(basePropertyConfig.getObjectId());
            basePropertyConfig_exist.setPropertyLevel(basePropertyConfig.getPropertyLevel());
            basePropertyConfigDAO.update(basePropertyConfig_exist);
        } else {
            String danWei = "单位:";
            String propertyName = basePropertyConfig.getPropertyName();
            if (StringUtils.isNotEmpty(propertyName) && propertyName.indexOf(danWei) > 0) {
                basePropertyConfig.setUnit(propertyName.substring(propertyName.indexOf(danWei) + 3, propertyName.indexOf(")")));
            }
            if (StringUtils.isNotEmpty(propertyName)) {
                if (propertyName.indexOf("(") > -1 && propertyName.indexOf(")") > -1) {
                    basePropertyConfig.setPropertyName(propertyName.substring(0, propertyName.indexOf("(")));
                    basePropertyConfig.setExplainData(propertyName.substring(propertyName.indexOf("(") + 1, propertyName.indexOf(")")));
                } else {
                    basePropertyConfig.setPropertyName(propertyName);
                    basePropertyConfig.setExplainData(propertyName);
                }
            }
            ServiceOpen serviceOpen = serviceOpenIntf.getServiceOpenById(Integer.parseInt(basePropertyConfig.getModuleId()));
            if (serviceOpen != null) {
                Service service = serviceOpenIntf.getServiceById(serviceOpen.getServiceId());
                if (service != null) {
                    basePropertyConfig.setModuleName(service.getServiceName());
                    basePropertyConfig.setModuleId(service.getServiceCode());
                }
                basePropertyConfig.setOpenServiceId(String.valueOf(serviceOpen.getId()));
            }
            basePropertyConfig.setObjectName(objectName);
            basePropertyConfigDAO.save(basePropertyConfig);
        }
    }

    /**
     * 初始化参数配置
     *
     * @param
     * @throws ControllerException
     */
    @Override
    @RpcService
    public void initBasePropertyConfig(String orgId) throws ControllerException {
        BasePropertyConfig basePropertyConfig = null;
        Dictionary svrOpenDic = null;
        Dictionary svrPropertyDic = null;
        try {
            svrOpenDic = DictionaryController.instance().get("hcn.base.dictionary.HCN_svrItemCode");
            svrPropertyDic = DictionaryController.instance().get("hcn.base.dictionary.HCN_svrOpenProperty");
            List<DictionaryItem> svrOpenItems = svrOpenDic.getSlice(null, 0, null);
            List<DictionaryItem> propertyItems = svrPropertyDic.getSlice(null, 0, null);
            ServiceProperty serviceProperty;
            //遍历机构开通的服务代码
            for (DictionaryItem svrOpenItem : svrOpenItems) {
                //服务代码
                String svrOpenKey = svrOpenItem.getKey();
                //服务名称
                String svrOpenName = svrOpenItem.getText();
                //获取该服务
                Service service = serviceOpenIntf.getServiceByCode(svrOpenKey);
                //初始化服务编码
                //若是服务不存在，就新增该服务
                if (null == service) {
                    service = new Service();
                    service.setServiceId(UUID.randomUUID().toString());
                    service.setServiceType(svrOpenKey.substring(0, 2));
                    service.setServiceCode(svrOpenKey);
                    service.setServiceName(svrOpenName);
                    service.setServiceDesc(svrOpenName);
                    service.setServiceGuide(svrOpenName);
                    service.setOrgServiceFlag("1");
                    service.setServicePaytype("1");
                    service.setDeptServiceFlag("0");
                    service.setDoctorServiceFlag("0");
                    service.setEffectiveFlag("1");
                    service.setServiceStackFlag("0");
                    service.setPlanFlag("0");
                    service.setUrgentFlag("0");
                    service.setUrgentFee(0D);
                    service.setCreateDt(new Timestamp(System.currentTimeMillis()));
                    service.setStartDt(new Timestamp(System.currentTimeMillis()));
                    serviceOpenIntf.saveService(service);
                }

                for (DictionaryItem propertyItem : propertyItems) {
                    //系统参数代码
                    String propertyKey = propertyItem.getKey();
                    //系统参数值
                    String propertyValue = propertyItem.getText();
                    //若是系统参数代码前四位和服务代码一致
                    if (propertyKey.substring(0, 4).equals(svrOpenKey)) {

                        //查询所有租户，初始化租户系统参数
                        List<Orgcloud> orgclouds = orgCloudIntf.findAll();
                        if (CommonUtils.isNotEmpty(orgclouds)) {
                            for (Orgcloud orgcloud : orgclouds) {
                                basePropertyConfig = basePropertyConfigIntf.getPropertyConfigByPropertyCode(propertyKey, orgcloud.getCloudId());
                                if (null == basePropertyConfig) {
                                    saveInitBasePropertyConfig(basePropertyConfig, service, propertyValue, propertyKey, svrOpenKey, "2", null, orgcloud.getCloudName(), orgcloud.getCloudId(), null);
                                }
                            }
                        }

                        //查询所有机构，初始化机构系统参数

                        List<Organization> allOrgMain = null;
                        if (CommonUtils.isNotEmpty(orgId)) {
                            Organization organization = organizationInfoIntf.getOrgDetailByOrgId(orgId);
                            if (null != organization) {
                                allOrgMain = new ArrayList<>();
                                allOrgMain.add(organization);
                            }
                        } else {
                            allOrgMain = organizationInfoIntf.findAllOrgMain(0, 0);
                        }


                        if (CommonUtils.isNotEmpty(allOrgMain)) {
                            for (Organization organization : allOrgMain) {
                                basePropertyConfig = basePropertyConfigIntf.getPropertyConfigByPropertyCode(propertyKey, organization.getOrgId());
                                if (null == basePropertyConfig) {
                                    saveInitBasePropertyConfig(basePropertyConfig, service, propertyValue, propertyKey, svrOpenKey, "3", null, organization.getFullName(), organization.getOrgId(), null);
                                }
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @description: 保存初始化的系统参数
     */
    @Override
    public void saveInitBasePropertyConfig(BasePropertyConfig basePropertyConfig, Service service, String propertyValue,
                                           String propertyKey, String svrOpenKey, String propertyLevel, Integer propertyId,
                                           String objectName, String objectId, String serviceOpenId) {

        basePropertyConfig = new BasePropertyConfig();
        String danWei = "单位:";
        String unit = "";
        if (propertyValue.indexOf(danWei) > 0) {
            unit = propertyValue.substring(propertyValue.indexOf(danWei) + 3, propertyValue.indexOf(")"));
        }
        if (propertyValue.indexOf("(") > -1 && propertyValue.indexOf(")") > -1) {
            basePropertyConfig.setExplainData(propertyValue.substring(propertyValue.indexOf("(") + 1, propertyValue.indexOf(")")));
            basePropertyConfig.setPropertyName(propertyValue.substring(0, propertyValue.indexOf("(")));
        } else {
            basePropertyConfig.setExplainData(propertyValue);
            basePropertyConfig.setPropertyName(propertyValue);
        }
        basePropertyConfig.setObjectName(objectName);
        basePropertyConfig.setOpenServiceId(serviceOpenId);
        basePropertyConfig.setModuleId(svrOpenKey);
        basePropertyConfig.setObjectId(objectId);
        basePropertyConfig.setPropertyCode(propertyKey);
        basePropertyConfig.setPropertyData(propertyValue.substring(propertyValue.indexOf("默认:") + 3));
        basePropertyConfig.setUnit(unit);
        basePropertyConfig.setPropertyId(propertyId);
        basePropertyConfig.setModuleName(service.getServiceName());
        basePropertyConfig.setPropertyLevel(propertyLevel);
        basePropertyConfigDAO.save(basePropertyConfig);
    }

    /**
     * 更新初始化系统参数
     *
     * @param propertyCode
     * @param orgId
     * @param propertyValue
     * @throws ControllerException
     */
    @Override
    public void updateBasePropertyConfig(String propertyCode, String orgId, String propertyValue) {
        BasePropertyConfig basePropertyConfig = basePropertyConfigDAO.getPropertyConfigByPropertyCode(propertyCode, orgId);
        if (CommonUtils.isNotEmpty(basePropertyConfig)) {
            basePropertyConfig.setPropertyData(propertyValue);
            basePropertyConfigDAO.update(basePropertyConfig);
        }
    }

    @Override
    public BasePropertyConfig getBasePropertyConfig(String propertyCode, String orgId) throws ControllerException {

        if (StringUtil.isEmpty(propertyCode)) {
            throw new ControllerException("系统参数编码不能为空");
        }
        ParameterVO paramByCode = ParamUtils.getParamByCode(PropertyCodeDTO.builder().propertyCode(propertyCode).functionId(golAppCode).build(),
                ObjectIdDTO.builder().orgId(orgId).build());
        if (Objects.isNull(paramByCode)) {
            return null;
        }
        BasePropertyConfig config = new BasePropertyConfig();
        config.setPropertyName(paramByCode.getName());
        config.setPropertyCode(paramByCode.getCode());
        config.setPropertyData(paramByCode.getValue());
        config.setUnit(paramByCode.getDes());
        return config;
    }

    /**
     * @deprecated 该方法可以被废弃 queryPropertyConfigByModuleId 提供了更加完善的功能,并且支持模糊查询
     */
    @Override
    @Deprecated
    public BasePropertyConfig getPropertyConfigByPropertyCode(String propertyCode, String objectId) {
        try {
            BasePropertyConfig basePropertyConfig = new BasePropertyConfig();
            if (StringUtil.isEmpty(propertyCode)) {
                throw new ControllerException("系统参数编码不能为空");
            }
            Parameter parameter = null;
            if (StringUtils.isEmpty(objectId)) {
                parameter = ParameterController.instance().get(propertyCode, null);
                basePropertyConfig.setPropertyCode(propertyCode);
                basePropertyConfig.setPropertyData(parameter.getDefaultValue());
                basePropertyConfig.setUnit(parameter.getDes());
                return basePropertyConfig;
            }

            ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
            if (objectId.contains(".")) {
                //租户id
                builder.put("1", objectId);
            } else {
                builder.put("41", objectId);
            }

            String multiValueByLimit = ParameterController.instance().getMultiValueByLimit(propertyCode, null, builder.build());
            basePropertyConfig.setPropertyCode(propertyCode);
            basePropertyConfig.setPropertyData(multiValueByLimit);
            return basePropertyConfig;
        } catch (Exception e) {
            LOGGER.info("查询系统参数错误： " + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<BasePropertyConfig> queryPropertyConfigList(String objectId, List<String> propertyCodes) throws ControllerException {

        ArrayList<BasePropertyConfig> propertyList = new ArrayList<>();
        if (CommonUtils.isEmpty(propertyCodes)) {
            throw new ControllerException("系统参数编码集不能为空");
        }
        for (String propertyCode : propertyCodes) {
            List<BasePropertyConfig> basePropertyConfigs = queryPropertyConfigByModuleId(objectId, propertyCode);
            if (CommonUtils.isNotEmpty(basePropertyConfigs)) {
                propertyList.addAll(basePropertyConfigs);
            }
//            BasePropertyConfig basePropertyConfig = getPropertyConfigByPropertyCode(propertyCode, objectId);
//            propertyList.add(basePropertyConfig);
        }
        return propertyList;
    }

    @Override
    @RpcAccess(auth = false)
    public List<BasePropertyConfig> queryPropertyConfigListWithoutToken(String tenantId, String objectId, List<String> propertyCodes) throws ControllerException {

        ArrayList<BasePropertyConfig> propertyList = new ArrayList<>();
        if (CommonUtils.isEmpty(propertyCodes)) {
            throw new ControllerException("系统参数编码集不能为空");
        }
        if (CommonUtils.isEmpty(tenantId)) {
            throw new ControllerException("tenantId不能为空");
        }
        String currentTenantId = UserRoleToken.getCurrentTenantId();
        if (CommonUtils.isEmpty(currentTenantId)) {
            ContextUtils.put("$tenantId", tenantId);
        }
        for (String propertyCode : propertyCodes) {
            List<BasePropertyConfig> basePropertyConfigs = queryPropertyConfigByModuleId(objectId, propertyCode);
            if (CommonUtils.isNotEmpty(basePropertyConfigs)) {
                propertyList.addAll(basePropertyConfigs);
            }
//            BasePropertyConfig basePropertyConfig = getPropertyConfigByPropertyCode(propertyCode, objectId);
//            propertyList.add(basePropertyConfig);
        }
        return propertyList;
    }


    /**
     * 查询参数限定值或者默认值 支持模糊查询
     *
     * @param objectId 租户id或者机构id
     * @param moduleId 参数key前缀
     */
    @Override
    public List<BasePropertyConfig> queryPropertyConfigByModuleId(String objectId, String moduleId) {
        PropertyCodeDTO propertyCodeDTO = PropertyCodeDTO.builder().propertyCode(moduleId).functionId(golAppCode).build();
        ObjectIdDTO objectIdDTO = ObjectIdDTO.builder().objectId(objectId).build();
        List<ParameterVO> params = ParamUtils.getParamsByModuleId(propertyCodeDTO, objectIdDTO);
        if (CommonUtils.isEmpty(params)) {
            return Collections.emptyList();
        }
        return params.stream().map(p -> {
            BasePropertyConfig config = new BasePropertyConfig();
            config.setPropertyName(p.getName());
            config.setPropertyCode(p.getCode());
            config.setPropertyData(p.getValue());
            config.setValidStartTime(p.getValidStartTime());
            config.setValidEndTime(p.getValidEndTime());
            config.setUnit(p.getDes());
            return config;
        }).collect(Collectors.toList());
    }

    /**
     * @deprecated 该方法废弃 无法获取实际的参数限定值, 只能获取系统参数默认值
     */
    @Deprecated
    public List<BasePropertyConfig> queryPropertyConfigByModuleIdBak(String objectId, String moduleId) throws Exception {

        if (StringUtils.isEmpty(moduleId)) {
            throw new ControllerException("模块id不能为空");
        }
        ArrayList<BasePropertyConfig> propertyList = new ArrayList<>();
        JSONResponseBean loadParams = ServiceAdapter.invokeWithJsonBytes("bbp.paramConfig", "loadParams", "", 1, 1000);
        LinkedHashMap<String, Object> body = (LinkedHashMap<String, Object>) loadParams.getBody();
        if (CommonUtils.isEmpty(body)) {
            return null;
        }
        List<LinkedHashMap<String, Object>> items = (ArrayList<LinkedHashMap<String, Object>>) body.get("items");
        for (LinkedHashMap<String, Object> map : items) {
            String cd = (String) map.get("cd");
            if (StringUtils.isNotEmpty(cd) && cd.contains(moduleId)) {
                BasePropertyConfig basePropertyConfig = new BasePropertyConfig();
                basePropertyConfig.setPropertyCode(cd);
                basePropertyConfig.setPropertyData((String) map.get("defaultValue"));
                basePropertyConfig.setUnit((String) map.get("des"));
                propertyList.add(basePropertyConfig);
            }
        }
        return propertyList;
        // return basePropertyConfigDAO.queryPropertyConfigByModuleId(objectId,moduleId);
    }

}
